import numpy as np
from matplotlib import pyplot as plt
from scipy.interpolate import interp1d
# 使用拉格朗日插值法，针对某个新的x值，返回一个插的y值
# 拉格朗日插值法容易出现荣格现象，故不经常使用
def Lagrange_interpolation(x_known, y_known, x_new):
    n = len(x_known)
    y_new = 0
    for i in range(n):
        p = y_known[i]
        for j in range(n):
            if j != i:
                p *= (x_new - x_known[j]) / (x_known[i] - x_known[j])
        y_new += p
    return y_new



y=[3,5,9,7,18,16,6,5,9,10]
x=np.linspace(0,9,num=10)
#x=[0,1,2,3,4,5,6,7,8,9]

#画出原始的序列
plt.figure()
plt.plot(x,y,'ro')
plt.legend()
plt.show()


#将原始序列分成多段,用一次函数拟合为函数f1和用三次函数拟合为函数f2
f1=interp1d(x,y,kind='linear')
f2=interp1d(x,y,kind='cubic')


#在原区间内均匀选取30个点,因为要插值到长度30.
x_pred=np.linspace(0,9,num=30)


#用函数f1求出插值的30个点对应的值
y1=f1(x_pred)
#用拉格朗日插值法求出插值的30个点对应的值
y_la = []
for i in x_pred:
    y_la.append(Lagrange_interpolation(x,y,i))
#在图中画出插值的30个点并连成曲线
# plt.figure()
# plt.plot(x,y,'bo')
# plt.plot(x_pred,y1,'-rx',label='linear')
# plt.plot(x_pred,y_la,'-ko',label='Lagrange')
# plt.legend()
# plt.show()

#用函数f2求出插值的30个点对应的值
y2=f2(x_pred)
#在图中画出插值的30个点并连成曲线
plt.figure()
plt.plot(x,y,'bo')
plt.plot(x_pred,y1,'-rx',label='linear')
plt.plot(x_pred,y_la,'-ko',label='Lagrange')
plt.plot(x_pred,y2,'-yx',label='cubic')
plt.legend()
plt.show()

